1. Technical Field
The invention relates to testing and validating software programs. In particular, the invention relates to testing and validating changes to printer graphic interpreter software that converts high level script to bitmaps.
2. Description of the Prior Art
Back in the 1970""s, ordinary personal-computer printers, such as the Centronics could only print characters on lines. The computer sent so-called ASCII-encoded 7-bit and 8-bit parallel digital signals to these printers and the printers knew how to print each character using a built-in font. Later, dot matrix type printers were sold that could do both character printing and some crude graphics. The advent of the inexpensive laser printer allowed far better graphics to be printed because the dot-density was as high as 300 dots-per-inch, and a whole bit-map could be downloaded that precisely described what was to be printed. But downloading bit-maps took a lot of processor time and memory storage to manipulate.
Because objects to be printed on paper can be described more efficiently using a high-level language than setting the exposure of every pixel in a bit-map, several printer control languages have now become universal. For example, Hewlett-Packard introduced PCL, and Adobe Systems introduced POSTSCRIPT. Many other such printer control languages also exist now, but they all convert or interpret the high-level language print job coming from the computer to the printer into a bit-map that represents the final printed page. Such bit-maps are used inside laser printers to set the exposure bit-by-bit on the xerographic drum that electrostatically picks up toner and deposits it on paper for thermal fusing.
PostScript is a computer programming language and a page description language. Unlike Basic and C, PostScript is designed to be executed rather than compiled. PostScript describes document pages in mathematical expressions. In its purest forms, PostScript describes the fonts, pages, and resources in a document as completely independent procedures. These can be extracted and used by other PostScript files, or by programs that manipulate PostScript pages, e.g. imposition programs.
PostScript describes everything on a page as graphic objects in terms of how to draw vectors. Rather than commanding the printer to put a dot here, put a dot there, PostScript instructs the printer to draw a line from here to here. This approach allows PostScript users to create files that produce the highest quality output a device can produce, whether the same file is sent to a high resolution imagesetter or an old Apple LaserWriter printer.
PostScript was introduced by Adobe in 1985 and first appeared in the Apple LaserWriter. The main purpose of PostScript was to provide a convenient language in which to describe images in a device independent manner. This device independence means that the image is described without reference to any specific device features. In practice, some PostScript files do make assumptions about the target device, such as its resolution or the number of paper trays.
The language itself is typically interpreted. It is stack-based, as is a reverse-Polish-notation calculator. The arguments are present first, and then the operators are loaded. For example, to add xe2x80x9c2+2xe2x80x9d, stack-based operating systems need to see entered, xe2x80x9c2, 2, +xe2x80x9d.
The device space is the coordinate space understood by the printer hardware. Such coordinate system is typically measured in terms of the device""s resolution. There is really nothing else that can be said about this space, as PostScript programs are typically not expressed using it. User space is the coordinate system used by PostScript programs to describe the location of points and lines. User space is essentially the same as the first quadrant of the standard coordinate system. Point (0, 0) is in the lower left corner. Coordinates are real numbers, so there is no set resolution in user space. The interpreter automatically converts user space coordinates into device space. The current transformation matrix is used for the transformation of user space coordinates to device space coordinates. Such matrix is a three-by-three matrix that allows the user to rotate, scale, and translate the entire user space within the device space.
A path is a collection of line segments and curves arranged on the page. The path does not describe actual ink on the paper. It merely describes an imaginary tracing over the page. There are operators which allow the user to draw or stroke ink along the path, fill an enclosed path with ink, and clip out all future images that are outside the path. The current path is the path that the PostScript program is creating at any one moment. The current path is assembled piece by piece. The PostScript rendering system ignores any part of a line segment, curve, or bitmap that extends outside a certain region. It only draws the parts of those elements which are within the region. The region is described by a path called the clipping path. The clipping path is usually a rectangle about a quarter of an inch in from the edge of the page, but it can easily be set by the user to an arbitrary path. The graphics state is a collection of various settings that describe the current state of the graphics system. For example, the current path, the current font, and the current transformation matrix are all parts of the graphics state.
A xe2x80x9ccommentxe2x80x9d in PostScript is any text preceded by a xe2x80x98%xe2x80x99. Many systems use a special comment, xe2x80x9c%!xe2x80x9d, as the first two characters of a PostScript program, to tag the file as PostScript code. There are several stacks in a PostScript system, but only two are needed to start learning POSTSCRIPT, e.g. the operand stack, and the dictionary stack. The operand stack is where arguments to procedures (or operators, in PostScript jargon) are pushed prior to use. The dictionary stack provides storage for variables. A dictionary is a collection of name-value pairs. All named variables are stored in dictionaries. Also, all available operators are stored in dictionaries along with their code. The dictionary stack is a stack of all currently open dictionaries. When a program refers to some key, the interpreter wanders down the stack looking for the first instance of that key in a dictionary. In this manner, names may be associated with variables and a simple form of scoping is implemented. Conveniently, dictionaries may be given names and be stored in other dictionaries. A name is any sequence of characters that can not be interpreted as a number. With the exception of spaces and certain reserved characters, any character may be part of a name. The name may even start with digits, xe2x80x9c1Zxe2x80x9d is a name, for example. A name is seen as being a reference to some value in a dictionary on the dictionary stack.
Programming in PostScript requires that operands be pushed onto the operand stack by naming them, and then invoking an operand to use them. The only real difficulty is knowing which operand to use. Operators to draw and put text on the screen make up the bulk of PostScript code, but there are a couple that are used mainly for maintaining the program itself. The first of these operators is def. xe2x80x9cdefxe2x80x9d is responsible for entering a definition into the top-most dictionary on the dictionary stack. The top operand on the operand stack is the value, and the operand below the value is the key, and should be a name. The xe2x80x9cdefxe2x80x9d operator can also be used to define new operators.
The main purpose of PostScript is to draw graphics on the page. In PostScript, even text is a kind of graphic. The main task that must be mastered, then, is constructing paths which may be used to create the image. To draw and fill shapes, the basic sequence is, 1) start the path with the newpath operator. Construct the path out of line segments and curves, and 2) draw the path with the stroke operator or fill it in with the fill operator. This basic sequence can be modified to do more complicated things.
The xe2x80x9clinetoxe2x80x9d operator works in absolute coordinates within user space. That is, xe2x80x9c72 72 linetoxe2x80x9d adds a line segment from the current point to the point (72, 72) in user space. In drawing the box, the absolute coordinates of the box""s vertices can be ignored. Only the lengths and directions of the box""s sides are important. PostScript includes a version of xe2x80x9clinetoxe2x80x9d that allows relative coordinates to be used instead, e.g. the xe2x80x9crlinetoxe2x80x9d operator. Such adds any coordinates given, as operands to the coordinates of the current point in the path, to find the destination point. That is, xe2x80x9c10 20 rlinetoxe2x80x9d draws a line from the current point to a point 10-points to the right and 20-points toward the top of the page. This is in contrast to xe2x80x9c10 20 linetoxe2x80x9d which adds a line segment which always ends at (10, 20).
Filling shapes is done by invoking the xe2x80x9cfillxe2x80x9d operator which fill the path with the current ink settings. xe2x80x9cFillxe2x80x9d uses a simple winding rule to determine what parts of the page are inside or outside the path. The regions that are inside are painted. Arbitrarily complex shapes can be filled with this operator.
It is often necessary to revise such interpreter software. The difficulty in the prior art has been in testing new versions of software for printer interpreters for hidden bugs in the programs. It typically takes a lot of time and resources, and has never been completely effective. It would be advantageous to provide a method or apparatus that tests revisions made to printer graphics interpreter software.
A method embodiment of the invention tests revisions made to printer graphics interpreter software. A test suite of POSTSCRIPT, PCL, or other high-level printer language is input to a production version of a printer""s internal interpreter software. A first bit-map is generated by the interpreter that is normally used to control each pixel in the printing of a page. The same test suite is fed to a work-in-progress revision of the printer""s internal interpreter software. A second bit-map is generated. The first and second bit-maps are subtracted from one another. A difference bit-map is inspected. If only minor shifts of objects are noted, or if no differences at all are apparent, the work-in-progress revision is accepted as the new production standard. The second bit-map is used to replace the first. Otherwise, the work-in-progress revision of the printer""s internal interpreter software is reworked to correct the printing interpretation errors it was making.